var pow = Math.pow
var exp = Math.exp
var abs = Math.abs
var sqrt = Math.sqrt
var E = Math.E

let engine = {
    // sound: (house_type, Dntw, C, day = true) => {

    // },
    sound_voice: () => {
        var values_sound1 = $("#sound1 option:selected").val();
        if (values_sound1 == 0) {
            let sound_day =$("#sound_voice_day").val();
            let sound_night =$("#sound_voice_night").val();
            if(sound_day<=35 &&sound_night<=30){
                return 3
            }else if(sound_day<=40 && sound_day>35 &&sound_night<=33 &&sound_night>30)
            {
                return 2
            }else if(sound_day<=45 && sound_day>40 &&sound_night<=37 &&sound_night>33){
                return 1
            }else{
                return 0
            }
        }
        else if (values_sound1 == 1) {
            let sound_voice =$("#sound_voice").val();
            if(sound_voice<=35){
                return 3
            }else if(sound_voice<=40 &&sound_voice>35){
                return 2
            }else if(sound_voice<=45 &&sound_voice>40){
                return 1
            }else{
                return 0
            }
        }
        else if (values_sound1 == 2) {
            let sound_voice =$("#sound_voice").val();
            if(sound_voice<=40){
                return 3
            }else if(sound_voice<=42 &&sound_voice>40){
                return 2
            }else if(sound_voice<=45 &&sound_voice>42){
                return 1
            }else{
                return 0
            }
        }
        else if (values_sound1 == 5) {
            let sound_voice =$("#sound_voice").val();
            if(sound_voice<=45){
                return 3
            }else if(sound_voice<=50 &&sound_voice>45){
                return 2
            }else if(sound_voice<=55 &&sound_voice>50){
                return 1
            }else{
                return 0
            }
        }
        else if (values_sound1 == 4) {
            let sound_voice =$("#sound_voice").val();
            if(sound_voice<=30){
                return 3
            }else if(sound_voice<=35 &&sound_voice>30){
                return 2
            }else if(sound_voice<=40 &&sound_voice>35){
                return 1
            }else{
                return 0
            }
        }
    },
    sound_insulation: () => {
        var values_sound2 = $("#sound2 option:selected").val();
        let sound_DnTW = $("#DnTW").val();
        let sound_Ctr = $("#Ctr").val();
        let sound_C = $("#C").val();
        let sound_D2mnTW = $("#D2mnTW").val();
        let sound_LnTW= $("#LnTW").val();

        if (values_sound2 == 0) {
            let sum = sound_DnTW+sound_Ctr
            if(sum>=55){
                return 3
            }else if(sum>=50 && sum<55)
            {
                return 2
            }else if(sum>=45 && sum<50){
                return 1
            }else{
                return 0
            }
        }
        else if (values_sound2 == 1) {
            let sum = sound_DnTW+sound_C
            if(sum>=50){
                return 3
            }else if(sum>=45 && sum<50)
            {
                return 2
            }else if(sum>=40 && sum<45){
                return 1
            }else{
                return 0
            }
        }
        else if (values_sound2 == 2) {
            let sum = sound_D2mnTW+sound_Ctr
            if(sum>=45){
                return 3
            }else if(sum>=40 && sum<45)
            {
                return 2
            }else if(sum>=35 && sum<40){
                return 1
            }else{
                return 0
            }
        }
        else if (values_sound2 == 3) {
            if(sound_LnTW<=65){
                return 3
            }else if(sound_voice<=70 &&sound_voice>65){
                return 2
            }else if(sound_voice<=75 &&sound_voice>70){
                return 1
            }else{
                return 0
            }
        }
    },


    // lx, Ra, U0, UGR, GR, R9, Tcp, strobe
    light: (house_type, params) => {

        let lev = standrad.light.data[house_type[0]]
        // 获取标准lev
        for (let index = 1; index < house_type.length; index++) {
            lev = lev[house_type[index]]
        }

        let reg = standrad.light.reg
        // 从最高等级向下匹配
        for (let index = lev.length - 1; index >= 0; index--) {
            let flag = true
            // 拿到最高级标准
            let strd = lev[index]
            for (let p in params) {
                let rp = params[p] // 传入的数据
                let sp = eval("strd" + p) // 标准值
                let com = reg[p.split("']")[0].replace('\'', '').replace('[', '')]
                console.log(rp + com + sp)
                // 如果达不到当前等级要求
                if (!eval(rp + com + sp)) {
                    flag = false
                    break
                }
            }
            // 如果达到当前要求
            if (flag) {
                return strd.L
            }
            // 如果没达到最低条件
            if (index == 0 && !flag) {
                return 0
            }
        }
    },
    heat: {
        PMV: (M, W, Pa, ta, fcl, ts, tcl, hc) => {
            return (0.303 * (E ** (-0.036 * M))) * (M - W - 3.05 * 1 / 1000 * (5733 - 6.99 * (M - W) - Pa) - 0.42 * (M - W - 58.15) - 1.7 * 1 / 100000 * M * (5867 - Pa) - 0.0014 * M * (34 - ta) - 3.96 * pow(10, -8) * fcl * (pow((tcl + 273), 4) - pow(ts + 273, 4)) - fcl * hc * (tcl - ta))
        },
        // 服装热阻 代谢率 对外做功 空气温度 平均辐射温度 空气流速 相对湿度 水蒸气分压力
        PMV_PPD: (clo, met, wme, ta, tr, vel, rh) => {

            var pa, icl, m, w, mw, fcl, hcf, taa, tra, tcla, p1, p2, p3, p4,
                p5, xn, xf, eps, hcn, hc, tcl, hl1, hl2, hl3, hl4, hl5, hl6,
                ts, pmv, ppd, n;

            pa = rh * 10 * exp(16.6536 - 4030.183 / (ta + 235));

            icl = 0.155 * clo
            m = met * 58.15
            w = wme * 58.15
            mw = m - w
            if (icl <= 0.078) fcl = 1 + (1.29 * icl);
            else fcl = 1.05 + (0.645 * icl);

            hcf = 12.1 * sqrt(vel);
            taa = ta + 273;
            tra = tr + 273;
            tcla = taa + (35.5 - ta) / (3.5 * icl + 0.1);

            p1 = icl * fcl;
            p2 = p1 * 3.96;
            p3 = p1 * 100;
            p4 = p1 * taa;
            p5 = 308.7 - 0.028 * mw + p2 * pow(tra / 100, 4);
            xn = tcla / 100;
            xf = tcla / 50;
            eps = 0.00015;

            n = 0;
            while (abs(xn - xf) > eps) {
                xf = (xf + xn) / 2;
                hcn = 2.38 * pow(abs(100.0 * xf - taa), 0.25);
                if (hcf > hcn) hc = hcf;
                else hc = hcn;
                xn = (p5 + p4 * hc - p2 * pow(xf, 4)) / (100 + p3 * hc);
                ++n;
                if (n > 150) {
                    alert('Max iterations exceeded');
                    return 1;
                }
            }

            tcl = 100 * xn - 273;

            hl1 = 3.05 * 0.001 * (5733 - (6.99 * mw) - pa);
            if (mw > 58.15) hl2 = 0.42 * (mw - 58.15);
            else hl2 = 0;
            hl3 = 1.7 * 0.00001 * m * (5867 - pa);
            hl4 = 0.0014 * m * (34 - ta);
            hl5 = 3.96 * fcl * (pow(xn, 4) - pow(tra / 100, 4));
            hl6 = fcl * hc * (tcl - ta);

            ts = 0.303 * exp(-0.036 * m) + 0.028;
            pmv = ts * (mw - hl1 - hl2 - hl3 - hl4 - hl5 - hl6);
            ppd = 100.0 - 95.0 * exp(-0.03353 * pow(pmv, 4.0) - 0.2179 * pow(pmv, 2.0));
            return {
                PMV: pmv,
                PPD: ppd
            }
        },
        // 局部空气温度 局部平均空气流速 局部紊流强度
        LPD1: (tal, val, Tu) => {
            if (val < 0.05) {
                val = 0.05
            }
            return (34 - tal) * pow((val - 0.05), 0.62) * (0.37 * val * Tu + 3.14)
        },
        // 头与踝部之间的垂直空气温度差
        LPD2: (deltaTav) => {
            return 100 / (1 + exp(5.76 - 0.856 * deltaTav))
        },
        // 地板表面平均温度
        LPD3: (tf) => {
            return 100 - 94 * exp(-1.387 + .118 * tf - 0.025 * (tf ** 2))
        },
        // PMV 气候区 建筑
        APMV: (PMV, region, build) => {
            let adapt = [{ // PMV >=0
                "严寒、寒冷地区": {
                    "居住建筑、商店建筑、旅馆建筑及办公室": 0.24,
                    "教育建筑": 0.21
                },
                "夏热冬冷、冬热夏暖、温和地区": {
                    "居住建筑、商店建筑、旅馆建筑及办公室": 0.21,
                    "教育建筑": 0.17
                }
            },// PMV < 0
            {
                "严寒、寒冷地区": {
                    "居住建筑、商店建筑、旅馆建筑及办公室": -0.5,
                    "教育建筑": -0.29
                },
                "夏热冬冷、冬热夏暖、温和地区": {
                    "居住建筑、商店建筑、旅馆建筑及办公室": -0.49,
                    "教育建筑": -0.28
                }
            }]
            let lambda = adapt[PMV >= 0 ? 0 : 1][region][build]

            return PMV / (1 + lambda * PMV)
        },
        // 人工冷热源热环境等级判定
        // 需要数据： 服装热阻 代谢率 对外做功 空气温度 平均辐射温度 空气流速 相对湿度 水蒸气分压力 
        // 局部空气温度 局部平均空气流速 局部紊流强度 头与踝部之间的垂直空气温度差 地板表面平均温度
        // 气候区 建筑
        // 需要参数： PPD、PMV、LPD1、LPD2、LPD3
        grade: (type, params) => {
            if (type.env == "人工冷热源热环境" && type.whole == "局部评价") {
                let lpd1 = level.heat.LPD1(params.tal, params.val, params.tu)
                let lpd2 = level.heat.LPD2(params.tav)
                let lpd3 = level.heat.LPD3(params.tf)
                if (lpd1 < 20 && lpd2 < 10 && lpd3 < 10) { return 3 }
                else if (lpd1 < 30 && lpd2 < 20 && lpd3 < 15) { return 2 }
                else if (lpd1 < 40 && lpd2 < 30 && lpd3 < 20) { return 1 }
                else { return 0 }
            }

            let pmv_ppd = level.heat.PMV_PPD(params.clo, params.met, params.wme, params.ta, params.tr, params.vel, params.rh)

            if (type.env == "人工冷热源热环境") {
                let pmv = abs(pmv_ppd.PMV)
                let ppd = pmv_ppd.PPD
                if (ppd <= 10 && pmv <= 0.5) { return 3 }
                else if (ppd <= 15 && pmv <= 0.7) { return 2 }
                else if (ppd <= 25 && pmv <= 0.1) { return 1 }
                else { return 0 }

            } else if (type.env == "非人工冷热源热环境") {
                let apmv = abs(level.heat.APMV(pmv_ppd.PMV, params.region, params.building))
                if (apmv > 1) { return 0 }
                else if (apmv > 0.7) { return 1 }
                else if (apmv > 0.5) { return 2 }
                else { return 3 }
            }
        }
    },
    air: (params) => {

    	if (params.hcho <= 0.03 && params.o3 <= 0.05 && params.pm10 <= 50 && params.pm25 <= 25 && params.tvoc <= 0.45 && params.c6h6 <= 0.07 && params.co2 <= 0.08 && params.nh3 <= 0.15) { return 3 }
        else if (params.hcho <= 0.07 && params.o3 <= 0.1 && params.pm10 <= 100 && params.pm25 <= 35 && params.tvoc <= 0.45 && params.c6h6 <= 0.07 && params.co2 <= 0.09 && params.nh3 <= 0.15) { return 2 }
        else if (params.hcho <= 0.08 && params.o3 <= 0.16 && params.pm10 <= 150 && params.pm25 <= 75 && params.tvoc <= 0.5 && params.c6h6 <= 0.09 && params.co2 <= 0.1 && params.nh3 <= 0.2) { return 1 }
        else { return 0 }
    },
    house_level: (sound, light, heat, air, subj) => {
        if (sound == 3 && light == 3 && heat == 3 && air == 3 && subj >= 80) { return 3 }
        else if (sound >= 2 && light >= 2 && heat >= 2 && air >= 2 && subj >= 70) { return 2 }
        else if (sound >= 1 && light >= 1 && heat >= 1 && air >= 1 && subj >= 60) { return 1 }
        else { return 0 }
    },
    building_level: (buildings) => {
        minscore = Math.min.apply(null, buildings)
        if (minscore < 1) { return 0 }
        else if (minscore < 2) { return 1 }
        else if (minscore < 3) { return 2 }
        return 3
    }
}

// console.log(level.light(["观演建筑", "观众厅", "影院"], { "['lx']": 250, "['Ra']": 86 }))
// console.log(level.light(['有电视转播的体育建筑', '冰球、花样滑冰、冰上舞蹈、短道速滑、速度滑冰'], {"['lx']['HDTV']": 2500}))
// console.log(level.heat.PMV_PPD(0.5, 1.2, 0, 22, 22, 0.1, 60))
// console.log(level.building_level([2, 3, 2, 3,2, 3]))
